package Solucion;

import java.util.ArrayList;

public class BrothersInArms {
	
	private ArrayList 	_datosOriginales = new ArrayList();
	private boolean		_error = false;
	
	private String[][]	_matrizOriginal;
	private String[][]	_matrizAuxiliar;
	private ArrayList	_resultados = new ArrayList();
	
	private int _herederos, _batallas;
	
	public int getLargoMatriz(){
		return this._matrizOriginal == null ? 0 : this._matrizOriginal.length;
	}
	
	public boolean hayErrores(){
		return this._error;
	}
	
	public BrothersInArms(String configuracion){
		if ( !configuracionOk(configuracion) ){ this._error = true; return; }		
		this._matrizOriginal 	= new String[Integer.valueOf(configuracion.substring(1, 2))][Integer.valueOf(configuracion.substring(2, 3))];
		this._matrizAuxiliar 	= new String[Integer.valueOf(configuracion.substring(1, 2))][Integer.valueOf(configuracion.substring(2, 3))];
		this._herederos 		= Integer.valueOf(configuracion.substring(0, 1));
		this._batallas 			= Integer.valueOf(configuracion.substring(3, 4));		
	}
	
	public void armarPartida(ArrayList matriz){		
		this._datosOriginales = matriz;
		if ( matriz == null || this._error || !matrizLineasOk(matriz) ){
			this._error = true;
			return;
		}
		
		for ( int i=0; i<matriz.size(); i++ ){			
			String s = (String) matriz.get(i);
			for ( int j=0; j<s.length(); j++ ){
				this._matrizOriginal[i][j] = s.substring(j, j+1);
				this._matrizAuxiliar[i][j] = s.substring(j, j+1);
			}			
		}		
	}
	
	private boolean configuracionOk(String c){		
		if ( c == null || c.trim().length() != 4 || !sonNumeros(c)) return false;
		if ( Integer.valueOf(c.substring(1, 2)) * Integer.valueOf(c.substring(2, 3)) < Integer.valueOf(c.substring(0, 1))) return false;
		for ( int i=0; i<c.length()-1; i++ ){
			int n = Integer.parseInt(c.substring(i,i+1));
			if ( n < 1 ) return false;
		}			
		return true;
	}
	
	private boolean sonNumeros(String n){
		boolean ret = true;		
		for ( int i=0; i<n.length(); i++ ){			
			try{
				int aux = Integer.parseInt(n.substring(i, i+1));
			}catch(Exception e){
				ret = false;
				break;
			}			
		}		
		return ret;
	}
	
	private boolean matrizLineasOk(ArrayList m){
		if ( m.size() != this._matrizOriginal.length ) return false;
		for ( int i=0; i<m.size(); i++ ){
			String s = (String) m.get(i);
			if ( s.length() != this._matrizOriginal[0].length || !sonNumeros(s) ) return false;
			for ( int j=0; j<s.length(); j++ ){
				int n = Integer.parseInt(s.substring(j, j+1));
				if ( n >= this._herederos ) return false;
			}			
		}		
		return true;
	}
	
	public void jugar(){
		if ( this._batallas == 0 || this._error){
			this._resultados = this._datosOriginales;
			return;
		}
		
		for ( int i=0; i<this._batallas; i++ ){
			
			for ( int j=0; j<this._matrizOriginal.length; j++ ){
				
				for ( int h=0; h<this._matrizOriginal[0].length; h++ ){					
					atacar( this._matrizOriginal[j][h] , j , h );					
				}				
			}			
			this._matrizOriginal = this._matrizAuxiliar;
			this._matrizAuxiliar = copiarMatriz(this._matrizOriginal);
		}
		
		for ( int i = 0; i<this._matrizOriginal.length; i++ ){
			String aux = "";
			for ( int j = 0; j<this._matrizOriginal[0].length; j++ ){
				aux += this._matrizOriginal[i][j];
			}
			this._resultados.add(aux);
		}
	}
	
	private void atacar(String v, int y, int x){
		int valor = Integer.parseInt(v);
		
		if ( x > 0 && ( valor == Integer.valueOf(this._matrizOriginal[y][x-1])-1 || (valor == this._herederos-1 && this._matrizOriginal[y][x-1].equals("0")) ) ) this._matrizAuxiliar[y][x-1] = String.valueOf(valor);
		if ( x < this._matrizOriginal[0].length-1 && ( valor == Integer.valueOf(this._matrizOriginal[y][x+1])-1 || (valor == this._herederos-1 && this._matrizOriginal[y][x+1].equals("0")) ) ) this._matrizAuxiliar[y][x+1] = String.valueOf(valor);
		if ( y > 0 && ( valor == Integer.valueOf(this._matrizOriginal[y-1][x])-1 || (valor == this._herederos-1 && this._matrizOriginal[y-1][x].equals("0")) ) ) this._matrizAuxiliar[y-1][x] = String.valueOf(valor);
		if ( y < this._matrizOriginal.length-1 && ( valor == Integer.valueOf(this._matrizOriginal[y+1][x])-1 || (valor == this._herederos-1 && this._matrizOriginal[y+1][x].equals("0")) ) ) this._matrizAuxiliar[y+1][x] = String.valueOf(valor);
			
	}
	
	private String[][] copiarMatriz(String[][] m){
		String[][] ret = new String[m.length][m[0].length];
		for ( int i=0; i<m.length; i++ ){
			for ( int j=0; j<m[0].length;j++ ){
				ret[i][j] = m[i][j];
			}
		}
		return ret;
	}
	
	public ArrayList getResultado(){
		return this._error ? this._datosOriginales : this._resultados;
	}
}
